using System;
using System.Collections.Generic;
using System.Text;

namespace RapidHDL.Fabric
{
    public class ControlState
    {
        string sName;

        Dictionary<string, ControlInput> dicControlInputs = new Dictionary<string, ControlInput>();

        ContainerBlock bkParentBlock;

        Output oOutput;
        Input oInput;

        public ControlState(ContainerBlock pbkParentBlock,string psName)
        {
            bkParentBlock = pbkParentBlock;
            sName = psName;
            oOutput = pbkParentBlock.CreateOutput(psName + "_O", 1);
            oInput = pbkParentBlock.CreateInput(psName + "_I", 1);
            oInput.IgnoreConnectionError = true;
        }

        public Input Input
        {
            get { return oInput; }
        }

        public Output Output
        {
            get { return oOutput; }
        }

        public string Name
        {
            get { return sName; }
        }

        public override string ToString()
        {
            return bkParentBlock.ToString() + "." + sName;
        }

        internal string ValidateStructure()
        {
            return "";
        }

        public void Activate(string psBlockName, string psControlName)
        {
            Block oBlock = bkParentBlock.Blocks[psBlockName];
            ControlInput oControlInput = oBlock.ControlInputs[psControlName];
            Activate(oControlInput);
        }

        public void Activate(ControlInput poControlInput)
        {
            poControlInput.JoinOR(oOutput);
        }

        public void Join(string psOutputBlockName, string psOutputName, string psInputBlockName, string psInputName)
        {
            Block oBlockIn = bkParentBlock.Blocks[psInputBlockName];
            Block oBlockOut = bkParentBlock.Blocks[psOutputBlockName];
            Input oInput = oBlockIn.Inputs[psInputName];
            Output oOutput = oBlockOut.Outputs[psOutputName];
            Join(oOutput, oInput);
        }

        public void Join(Output poOutput, Input poInput)
        {
            ControlInput oControlInput = poInput.JoinWithSelect(poOutput);
            Activate(oControlInput);            
        }

        public string FullName
        {
            get { return this.ToString().Replace('.', '_'); }
        }

        public void GenerateStructure(Component poParentComponent)
        {
            /*if (sName == "NOP")
                throw new Exception("Hai");*/
            string sControlName = "STATE_" + Name;
            NodeVector nvControlLine = poParentComponent.CreateNodeVector(sControlName, 1);
            oInput.LinkNodeVector(nvControlLine);
            oOutput.LinkNodeVector(nvControlLine);

            //jake jake here
            //is the connection flowing from the toplevel component to the nvControlLine?
            //it could be that the control line is getting replaced for the output
            // or something..
            // symptom seen here is the signal source doesn't match what is read out
        }
    }
}
